<template>
  <div class="chat-container-wrapper">
    <div class="chat-container-wrapper">
      <ReportContainer
        class="report-container"
        v-if="showReport"
        :processId="reportId"
        @closeReport="handelCloseReport"
        @goLogin="goLogin"
        @reportBodyType="reportBodyType"
      />
      <CustomModel
        v-if="showViewer"
        type="media"
        :options="showViewerOptions"
        @closeModel="closeModel"
      />
      <div
        class="chat-dialogue-container"
        id="chatbox"
        @scroll="handleScrollChange"
      >
        <div class="chatpop-single-wrapper">
          <ChatWelcome
            v-if="showWelcome"
            @clickMenu="startDialog"
            @goLogin="goLogin"
          />
        </div>
        <div
          class="chatpop-single-wrapper"
          v-for="(item, index) in dialogues"
          :key="index"
          :ref="`chat${
            item.processId && item.type == 'doctor' ? item.processId : index
          }`"
          :data-index="index"
          :data-item="JSON.stringify(item)"
        >
          <ChatPop
            :loading="loading === index"
            :typing="typing !== false"
            :message="item"
            :msg="item.msg"
            :ref="'chatpop' + index"
            :stopCurrentAnswer="loading === index || typing === index"
            @previewMedia="previewMedia"
            @showReport="handelShowReport"
            @stopAnswer="handelStopAnswer"
          />
          <!-- <div class="chat-loading" v-if="loading === index">停止生成</div> -->
          <ChatFeedback
            v-if="ifShowFeedback(item, index)"
            :probList="probList"
            :groupProcessId="item.groupProcessId"
            :processId="item.processId"
            :reAnswer="
              index == dialogues.length - 1 && item.contentType != 'report'
            "
            :switchAnswer="switchAnswer[index] && switchAnswer[index].total > 1"
            :totalAnswerNum="
              switchAnswer[index] ? switchAnswer[index].total : null
            "
            :currentNum="
              switchAnswer[index] ? switchAnswer[index].current : null
            "
            :currentLiketype="
              switchAnswer[index] ? switchAnswer[index].currentLiketype : null
            "
            @feedbackStatusChange="handelFeedback"
            @reanswer="handelReanswer"
            @switchAnswerContent="handelSwitchAnswer"
            @copy="handleCopy(item)"
          />
          <div
            class="recommend-question-wrapper"
            v-if="ifShowQues(item, index)"
          >
            <span class="recommend-question-text">为您推荐：</span>

            <div class="recommend-question">
              <div
                class="recommend-single upload-tongue"
                v-if="innerAppMenuId == 1 && dialogues.length == 1"
                @click="handelImageUpload"
              >
                <img
                  class="up-icon"
                  src="../../assets/image/recom-upload-icon.png"
                />
                <span class="up-text">上传舌像</span>
              </div>
              <div
                class="recommend-single"
                v-for="(ques, quesIndex) in recomQues"
                :key="quesIndex"
                @click="handelRecomQues(ques)"
              >
                {{ ques }}
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="chat-footer">
        <div class="footer-input-container">
          <el-input
            class="user-input"
            placeholder="请输入您要问的问题..."
            type="textarea"
            :autosize="{ maxRows: 8 }"
            v-model="inputText"
            maxlength="1000"
            show-word-limit
            @keydown.enter.native="handleSend"
          />
          <!-- <el-upload
            class="upload-demo"
            ref="upload"
            action=""
            :show-file-list="false"
            :auto-upload="false"
            :on-change="uploadImage"
          > -->
          <div class="user-operation">
            <img
              slot="trigger"
              class="user-upload-icon"
              src="../../assets/image/upload-img.png"
              @click="handelImageUpload"
            />
            <!-- </el-upload> -->

            <el-button
              class="user-text-send"
              type="primary"
              icon="el-icon-s-promotion"
              @click="handleSend"
              >发送</el-button
            >
          </div>
        </div>
        <div class="footer-notice">
          内容由AI生成，仅供参考，请遵守<span
            class="agreement"
            @click="showAgeement"
            >《萌医大模型用户协议》</span
          >，基于萌医大模型，版本v1.0.1
        </div>
      </div>
    </div>
  </div>
</template>

<script>
  import request from '../../utils/request'
  import ChatPop from './chatPop.vue'
  import ChatFeedback from './chatFeedback.vue'
  import ChatWelcome from './chatWelcome.vue'
  import ReportContainer from './reportContainer.vue'
  import CustomModel from '../../components/customModel.vue'
  export default {
    name: 'ChatContainer',
    props: {
      history: [String, Number], // 历史记录
      appMenuId: [String, Number],
      answeUserId: [String, Number],
      userId: [String, Number],
      imageList: Array,
      imageUrlList: Array,
    },
    components: {
      ChatPop,
      ChatFeedback,
      ChatWelcome,
      ReportContainer,
      CustomModel,
    },
    data() {
      return {
        imgBaseUrl: 'http://chunfengai.top:29001/download/',
        userInfo: JSON.parse(localStorage.getItem('userInfo')),
        // userId: localStorage.getItem('userId'),
        inDailog: false,
        dialogues: [],
        dialogueId: '',
        recomQues: [],
        typing: false,
        loading: false,
        wsDroppingAnswer: false,
        switchAnswer: {},
        inputText: '',
        newDialogId: undefined,
        ws: undefined,
        showWelcome: true,
        showReport: false,
        reportId: '',
        innerAppMenuId: '',
        showViewer: false,
        showViewerOptions: { url: '', title: '' },
        currentImageStep: 1,
        imageNameList: [],
        chatpopKey: 0,
        currentImageURL: '',
        reportDefQues: [
          '我的体质是什么',
          '请给我一些调理建议',
          '请分析下上述舌象具体的体质',
        ],
        probList: [],
        autoScroll: true,
        lastScrollHeight: 0,
      }
    },
    computed: {
      // answeUserId() {
      //   return this.userInfo.answeUserId
      // },
    },
    watch: {
      // id(n, o) {
      //   if (n == -1) {
      //     this.newDialogId = undefined
      //     this.showWelcome = true
      //     this.dialogues = []
      //     this.requireNewDialogue()
      //   } else if (n != this.newDialogId) {
      //     this.newDialogId = undefined
      //     this.showWelcome = false
      //     this.dialogues = []
      //     this.requireHistory()
      //   }
      // },
      history(n, o) {
        console.log('history change :>> ', n, o)
        if (n) {
          this.inDailog = true
          this.dialogueId = n
          this.requireHistory(n)
        }
        // this.requireHistory(n)
      },
      dialogues: {
        deep: true,
        handler(n, o) {
          if (n.length > 0) {
            this.showWelcome = false
          }
          // let chatbox = document.getElementById('chatbox')
          // this.$nextTick(() => {
          //   chatbox.scrollTop = chatbox.scrollHeight
          // })
          this.handelScroll()
          // console.log(
          //   'watch dialog :>> ',
          //   chatbox.scrollTop,
          //   chatbox.scrollHeight
          // )
          this.chatpopKey += 1
          // console.log('key in watch :>> ', this.chatpopKey)
        },
      },
      imageList: {
        deep: true,
        handler(n, o) {
          this.imageNameList = n
          // this.imageUrlList.forEach((item) => {
          //   if (item == undefined) return
          //   this.dialogues.push({
          //     type: 'oner',
          //     msg: '',
          //     contentType: 'img',
          //     imgUrl: item,
          //   })
          // })
          this.dialogues.push({
            type: 'oner',
            msg: '',
            contentType: 'tongue-img',
            imgUrl: this.imageUrlList.filter((i) => i != undefined),
          })
          this.requireChatWithImage()
        },
      },
      recomQues(n, o) {
        this.handelScroll()
      },
      // innerAppMenuId(n, o) {
      //   this.handleBreadcrumb(this.dialogues.length == 0 ? -1 : n)
      // },
    },
    created() {
      new Promise((resolve, reject) => {
        // debugger
        if (this.userId) {
          resolve()
        } else {
          reject('login')
        }
      })
        .then((res) => {
          this.initWebSocket()
          this.requireProbList()
          console.log('create chat container :>> ')
          if (this.history) {
            this.inDailog = true
            this.dialogueId = this.history
            this.showWelcome = false
            this.requireHistory(this.history)
          }
          this.innerAppMenuId = this.appMenuId > 0 ? this.appMenuId : 2006
        })
        .catch((err) => {
          if (err == 'login') {
            console.log('show login in create chat:>> ', err)
            this.$emit('goLogin')
          } else {
            // location.reload()
            console.log('error create chat:>> ', err)
          }
          //
        })
    },
    mounted() {},
    updated() {},
    beforeDestroy() {
      this.ws && this.ws.close()
    },
    methods: {
      setData(obj) {
        Object.keys(obj).forEach((key) => {
          this[key] = obj[key]
        })
      },
      handleBreadcrumb(e) {
        this.$emit('currentMenuChange', e)
      },
      handelScroll() {
        // if (this.loading || this.typing) return
        console.log('handlescroll :>> ')
        if (!this.autoScroll) return
        let chatbox = document.getElementById('chatbox')
        // if(chatbox.scrollTop == chatbox.scrollHeight)
        this.$nextTick(() => {
          chatbox.scrollTop = chatbox.scrollHeight
        })
      },
      handleScrollChange(e) {
        let chatbox = document.getElementById('chatbox')
        let minHeight = chatbox.clientHeight
        console.log(
          'handleScrollChange :>> ',
          chatbox.scrollHeight,
          chatbox.scrollTop,
          chatbox.scrollHeight - chatbox.scrollTop,
          chatbox.clientHeight
        )

        if (chatbox.scrollHeight - chatbox.scrollTop > minHeight) {
          this.autoScroll = false
        } else {
          this.autoScroll = true
        }
      },
      valueGetter(val) {
        if (val) {
          return val
        } else {
          this.$emit('goLogin')
          return {}
        }
      },
      showAgeement() {
        this.$emit('showAgeement')
      },
      ifShowQues(item, index) {
        if (item.type != 'doctor') {
          return false
        }
        if (item.contentType != 'text' && item.contentType != 'report') {
          return false
        }
        if (this.recomQues.length == 0) {
          return false
        }
        if (index != this.dialogues.length - 1) {
          return false
        }
        return true
      },
      ifShowFeedback(item, index) {
        if (item.type == 'oner') {
          return false
        }
        if (item.isWelcome) {
          return false
        }
        // if (this.loading == index) {
        //   return false
        // }
        if (this.typing == index) {
          return false
        }
        if (item.contentType != 'text' && item.contentType != 'report') {
          return false
        }
        return true
      },
      reportBodyType() {
        this.inputText = '我的体质是什么'
        this.handleSend()
        this.handelCloseReport()
      },
      handelShowReport() {
        this.showReport = true
      },
      handelCloseReport() {
        this.showReport = false
      },
      async uploadImage(file) {
        console.log('file :>> ', file)
        let formData = new FormData()
        formData.append('file', file.raw)
        this.currentImageURL = URL.createObjectURL(file.raw)
        console.log('imageurl :>> ', this.currentImageURL)
        let params = {
          method: 'POST',
          url: `/applet/dialog/pic/checkpic?userId=${this.userId}&answeUserId=${this.answeUserId}&type=${this.currentImageStep}`,
          data: formData,
        }

        this.dialogues.push({
          type: 'oner',
          msg: '',
          contentType: 'img',
          imgUrl: this.currentImageURL,
        })
        this.loading = this.dialogues.length - 1
        this.req(params).then((res) => {
          console.log('upload :>> ', res)
          if (res.data.data.uploadFileName) {
            this.imageNameList[this.currentImageStep - 1] =
              res.data.data.uploadFileName

            this.requireChatWithImage()
          } else {
            this.$message('请稍后重试')
          }
        })
      },
      async getLocalImageURL(file) {
        let url = await new Promise((reject, resolve) => {
          const reader = new FileReader()
          reader.readAsDataURL(file)
          reader.onload = () => resolve(reader.result)
          reader.onerror = (error) => reject(error)
        })
        return url
      },
      previewMedia(options) {
        console.log('previewMedia :>> ', options)
        this.showViewerOptions = options
        this.showViewer = true
      },
      closeModel() {
        this.showViewer = false
      },
      newDialog() {
        this.requireNewDialogue()
      },
      handelStopAnswer() {
        clearInterval(this.i)
        // this.wsDroppingAnswer = true
        this.requireBreak()
        this.loading = false
        this.typing = false
      },
      handelSwitchAnswer(e) {
        console.log('switch :>> ', e)
        let index = this.$refs['chat' + e.processId][0].dataset.index
        let switchType = e.type
        let dialogues = this.dialogues
        let switchAnswer = this.switchAnswer
        let currentSwitchAnswer = this.switchAnswer[index]
        console.log('sw index  :>> ', index, currentSwitchAnswer)
        if (switchType == -1) {
          if (currentSwitchAnswer.current == 1) {
            return
          } else {
            // dialogues.pop(index)
            currentSwitchAnswer.current -= 1
            currentSwitchAnswer.currentLiketype =
              currentSwitchAnswer.contents[
                currentSwitchAnswer.current - 1
              ].likeType
            dialogues.splice(
              index,
              1,
              JSON.parse(
                currentSwitchAnswer.contents[currentSwitchAnswer.current - 1]
                  .prompt
              )
            )
          }
        } else {
          if (currentSwitchAnswer.current == currentSwitchAnswer.total) {
            return
          } else {
            // dialogues.pop(index)
            currentSwitchAnswer.current += 1
            currentSwitchAnswer.currentLiketype =
              currentSwitchAnswer.contents[
                currentSwitchAnswer.current - 1
              ].likeType
            dialogues.splice(
              index,
              1,
              JSON.parse(
                currentSwitchAnswer.contents[currentSwitchAnswer.current - 1]
                  .prompt
              )
            )
          }
        }
        // console.log('switch>>', JSON.stringify(currentSwitchAnswer))
        switchAnswer[index] = currentSwitchAnswer
        this.setData({ switchAnswer, dialogues })
      },
      handelReanswer(e) {
        console.log('reanswer :>> ', this.$refs['chat' + e])
        let item = JSON.parse(this.$refs['chat' + e][0].dataset.item)
        let index = JSON.parse(this.$refs['chat' + e][0].dataset.index)
        try {
          this.switchAnswer[index].currentLiketype = 0
        } catch (error) {
          if (error instanceof TypeError) {
            this.switchAnswer[index] = {}
            this.switchAnswer[index].currentLiketype = 0
            // 处理 TypeError 错误
          } else {
            // 处理其他类型的错误
            console.log('error in handelReanswer :>> ', error)
          }
        }

        this.requireReanswer(item.processId, index)
      },
      handelFeedback(e) {
        console.log('feedback :>> ', e)
        let index = this.$refs['chat' + e.processId][0].dataset.index
        let t = this.switchAnswer[index]
        this.switchAnswer[index].currentLiketype = e.likeType
        this.switchAnswer[index].contents[t.current - 1].likeType = e.likeType
        if (!e.groupProcessId) {
          console.warn('groupProcessId required:>> ', e)
          return
        } else {
          this.requireFeedback(e)
        }
      },
      handleCopy(item) {
        // let el=document.createElement('textarea')
        // el.value=item.msg
        // el.style.display='none'
        // document.body.appendChild(el)
        // el.select()
        // console.log('copy item.msg :>> ', item.msg)
        let text = item.msg.replaceAll(/<a\b[^>]*>(.*?)<\/a>/g, '$1')
        // text = item.msg.replaceAll(/<\/a>/g, '')
        try {
          navigator.clipboard
            .writeText(text)
            .then(() => {
              this.$message({
                message: '复制成功！',
                type: 'success',
              })
              // console.log('copy to clipboard :>> ', text)
            })
            .catch((err) => {
              console.log('copy failed :>> ', err)
            })
        } catch (e) {
          let el = document.createElement('textarea')
          el.value = text
          // el.style.display = 'none'
          document.body.appendChild(el)
          el.focus()
          el.select()
          try {
            console.log('el :>> ', el)
            new Promise((res, rej) => {
              document.execCommand('copy') ? res() : rej()
            })
              .then((res) => {
                this.$message({
                  message: '复制成功！',
                  type: 'success',
                })
                el.remove()
              })
              .catch((e) => {
                console.log('document.execCommand promise error :>> ', e)
              })
          } catch (e) {
            console.log('document.execCommand error', e)
          }
        }
      },
      handleInputChange(e) {
        console.log('this.inputText :>> ', e)
      },
      handelImageUpload() {
        console.log('handel up :>> ')
        this.$emit('showUploadModel')
      },
      handleSend(e) {
        if (e) {
          e.preventDefault()
          console.log('e :>> ', e)
        }
        console.log('send :>> ', this.inputText)
        // if (!this.userInfo) {
        //   this.$emit('goLogin')
        //   return
        // }
        this.autoScroll = true
        this.handelScroll()
        this.recomQues = []
        if (this.loading || this.typing) {
          this.$message('回答中，请稍候……')
          return
        }
        if (this.inputText == '') {
          this.$message('请输入问题')
          return
        }
        this.dialogues.push({
          type: 'oner',
          msg: this.inputText,
          contentType: 'text',
        })
        this.loading = this.dialogues.length - 1
        if (!this.inDailog) {
          this.requireNewAndSend()
        } else {
          this.requireChat()
          this.inputText = ''
        }
      },
      handelRecomQues(ques) {
        this.recomQues = []
        this.dialogues.push({
          type: 'oner',
          msg: ques,
          contentType: 'text',
        })
        if (!this.inDailog) {
          this.requireNewAndSend(ques)
        } else {
          this.requireChat(ques)
        }
        // this.requireChat(ques)
      },
      isReanswer(processId) {
        let i = -1
        this.dialogues.forEach((item, index) => {
          if (item.processId == processId) {
            i = index
          }
        })
        return i
      },
      formatMsgToData(list, isHistory = false) {
        /**
         * 格式化 历史消息 消息推送为页面上可以展示的消息
         * prompType==2:cv报告文字，contentType="report"，加打字机效果，显示跳转报告
         * prompType==3:大模型文字，contentType="text"，流式接收
         * else:图，contentType="img"
         */
        const arr = this.dialogues
        if (isHistory) {
          /**历史消息 */
          list.forEach((e) => {
            console.log('his>>', e)
            if (e.prompt === 'isOnlineSucc') {
              return
            }
            switch (e.promptType) {
              case 0:
                arr.push({
                  type: e.type,
                  msg: e.type === 'oner' ? e.prompt : JSON.parse(e.prompt),
                  contentType: 'text',
                  processId: e.processId || '',
                  groupProcessId: e.groupProcessId || '',
                })
                break
              case 3:
                arr.push({
                  type: e.type,
                  msg: e.type === 'oner' ? e.prompt : JSON.parse(e.prompt),
                  contentType: 'text',
                  processId: e.processId || '',
                  groupProcessId: e.groupProcessId || '',
                })
                break
              case 2:
                arr.push({
                  type: e.type,
                  msg: e.type === 'oner' ? e.prompt : JSON.parse(e.prompt),
                  contentType: 'report',
                  processId: e.processId || '',
                  groupProcessId: e.groupProcessId || '',
                })
                this.reportId = e.processId
                break
              default:
                if (e.type == 'doctor') {
                  arr.push({
                    type: e.type,
                    contentType: 'img',
                    imgUrl: `data:image/png;base64,${e.prompt}`,
                    processId: e.processId || '',
                    groupProcessId: e.groupProcessId || '',
                  })
                } else if (e.type == 'oner') {
                  if (arr.length == 0) {
                    arr.push({
                      type: e.type,
                      contentType: 'tongue-img',
                      imgUrl: [`data:image/png;base64,${e.prompt}`],
                      processId: e.processId || '',
                      groupProcessId: e.groupProcessId || '',
                    })
                    break
                  }
                  let last = arr[arr.length - 1]

                  if (last.contentType == 'tongue-img') {
                    arr[arr.length - 1].imgUrl.push(
                      `data:image/png;base64,${e.prompt}`
                    )
                  } else {
                    arr.push({
                      type: e.type,
                      contentType: 'tongue-img',
                      imgUrl: [`data:image/png;base64,${e.prompt}`],
                      processId: e.processId || '',
                      groupProcessId: e.groupProcessId || '',
                    })
                  }
                }
                break
            }
            this.dialogues = arr
            this.addToAnswersList(arr[arr.length - 1], arr.length - 1)
          })
        } else {
          this.loading = false
          /**非历史消息 websocket一次接收到1条*/
          let t = list[0]
          if (t.recomQues) {
            this.recomQues = JSON.parse(t.recomQues)
          }
          if (t.type == 'doctor') {
            // console.log('doctor>>')
            switch (t.promptType) {
              case 0:
                arr[arr.length - 1] = {
                  type: t.type,
                  msg: t.prompt,
                  contentType: 'text',
                  processId: t.processId || '',
                  groupProcessId: t.groupProcessId || '',
                }
                this.dialogues = arr
                this.typing = false
                this.loading = false

                break
              case 2:
                /**cv=>打字机 */
                this.typing = arr.length - 1
                this.loading = false
                arr.pop()
                arr.push({
                  type: t.type,
                  msg: '',
                  contentType: 'report',
                  processId: t.processId || '',
                  groupProcessId: t.groupProcessId || '',
                })

                this.dialogues = arr
                // console.log('setdialog>>', t)
                let dialog = JSON.parse(t.prompt)
                  .replaceAll(/\n/g, '<br/>')
                  .split('')
                let _this = this

                this.i = setInterval(() => {
                  if (dialog.length == 0) {
                    clearInterval(_this.i)
                    _this.addToAnswersList(
                      _this.dialogues[_this.dialogues.length - 1],
                      _this.dialogues.length - 1
                    )
                    _this.recomQues = _this.reportDefQues
                    _this.setData({ typing: false, loading: false })
                  } else {
                    arr[arr.length - 1].msg += dialog.shift()
                    _this.setData({
                      dialogues: arr,
                    })
                  }
                }, 10)
                break
              case 3:
                // console.log('case3>>',t)
                /**流式回答 */
                let re = this.isReanswer(t.processId)
                if (t.isFinish == -1) {
                  /**第一次接收 */
                  // let lastProcessId = arr[arr.length - 1].processId
                  let content = {
                    type: t.type,
                    msg: JSON.parse(t.prompt),
                    contentType: 'text',
                    processId: t.processId || '',
                    groupProcessId: t.groupProcessId || '',
                    likeType: 0,
                  }
                  if (re >= 0) {
                    /**processId和某一条一样=>重新生成的答案*/
                    // arr.pop(re)
                    arr.splice(re, 1)
                    this.dialogues = arr
                    arr.splice(re, 0, content)
                    this.dialogues = arr
                    // arr[re] = content
                    // console.log(
                    //   'key in case3 finish-1 re :>> ',
                    //   this.chatpopKey
                    // )
                    this.chatpopKey += 1
                    // let switchAnswer = this.switchAnswer
                    console.log('switchAnswer :>> ', JSON.stringify(arr[re]))
                    this.switchAnswer[re].total += 1
                    this.switchAnswer[re].current = this.switchAnswer[re].total
                    this.switchAnswer[re].currentLiketype = 0
                    this.typing = re
                  } else {
                    /**新回答 */
                    // console.log('key in case3 finish-1 :>> ', this.chatpopKey)
                    this.chatpopKey += 1
                    this.dialogues.pop()
                    this.dialogues.push(content)
                    this.typing = this.dialogues.length - 1
                  }

                  this.dialogues = arr
                  this.$forceUpdate()
                } else if (t.isFinish == 0) {
                  /**继续接收 */
                  if (this.wsDroppingAnswer) {
                    console.log(
                      'wsDroppingAnswer>>',
                      this.wsDroppingAnswer,
                      t.isFinish
                    )
                    /**已点停止生成 */
                    return
                  }

                  if (re >= 0) {
                    console.log('re :>> ', re)
                    let [cur] = this.dialogues.splice(re, 1)
                    cur.msg = JSON.parse(t.prompt)
                    this.dialogues.splice(re, 0, cur)
                    // console.log('key in case3 finish0 :>> ', this.chatpopKey)
                    // arr[re].msg = JSON.parse(t.prompt)
                  } else {
                    this.dialogues[this.dialogues.length - 1].msg = JSON.parse(
                      t.prompt
                    )
                  }
                  this.chatpopKey += 1

                  // console.log('ws answer>>', t.isFinish)
                  // this.dialogues = arr
                  // this.$forceUpdate()
                  // this.$set(this.dialogues[re],re,arr[re])
                } else {
                  /**结束 */
                  if (!this.wsDroppingAnswer) {
                    arr[re].msg = JSON.parse(t.prompt)
                    this.dialogues = arr
                    // this.$forceUpdate()
                  }
                  this.typing = false
                  this.loading = false
                  this.wsDroppingAnswer = false
                  /**存到switchAnswer */
                  this.addToAnswersList(this.dialogues[re], re)
                }

                break
              default:
                arr.push({
                  type: t.type,
                  contentType: 'img',
                  imgUrl: `data:image/png;base64,${t.prompt}`,
                  processId: t.processId || '',
                  groupProcessId: t.groupProcessId || '',
                })
            }
          } else {
            /**其他情况：正常 */
            if (t.prompt === 'isOnlineSucc') {
              return
            }
            if (t.promptType === 0) {
              arr.push({
                type: t.type,
                msg: t.type === 'oner' ? t.prompt : JSON.parse(t.prompt),
                contentType: 'text',
                processId: t.processId || '',
                groupProcessId: t.groupProcessId || '',
              })
            } else {
              arr.push({
                type: t.type,
                contentType: 'img',
                imgUrl: `data:image/png;base64,${t.prompt}`,
                processId: t.processId || '',
                groupProcessId: t.groupProcessId || '',
              })
            }
            this.setData({
              dialogues: arr,
              loading: false,
              typing: false,
            })
          }
        }
      },
      addToAnswersList(arrObject, index) {
        /**存进switchAnswer */
        // let switchAnswer = this.switchAnswer
        if (this.switchAnswer[index]) {
          //该问题已有多个回答
          this.switchAnswer[index].contents.push({
            prompt: JSON.stringify(arrObject),
            likeType: 0,
          })
          this.switchAnswer[index].currentLiketype = 0
        } else {
          //第一次重新回答
          let content = {
            contents: [{ prompt: JSON.stringify(arrObject), likeType: 0 }],
            currentLiketype: 0,
            current: 1,
            total: 1,
          }
          this.$set(this.switchAnswer, index, content)
          // this.switchAnswer[index] =content
        }
        // this.setData({ switchAnswer })
        console.log('save switchAnswer>>', this.switchAnswer)
      },
      initWebSocket() {
        //初始化weosocket
        let wsurl = `ws://chunfengai.top:28081/websocket/chat/${this.userId}`
        this.ws = new WebSocket(wsurl)
        this.ws.onmessage = this.websocketonmessage
        this.ws.onopen = this.websocketonopen
        this.ws.onerror = this.websocketonerror
        this.ws.onclose = this.websocketclose
      },
      websocketonmessage(e) {
        const content = JSON.parse(e.data)
        // console.log('ws message :>> ', content)
        this.formatMsgToData([content])
      },
      websocketonopen() {
        console.log('ws open :>> ', this.ws.readyState)
      },
      websocketonerror() {
        console.log('ws error :>> ')
      },
      websocketclose(e) {
        console.log('ws close :>> ', this.ws.readyState, e)
      },
      goLogin() {
        this.$emit('goLogin')
      },
      startDialog(item) {
        this.showWelcome = false
        this.typing = true
        this.innerAppMenuId = item.menuId
        this.handleBreadcrumb(this.innerAppMenuId)
        let texts = item.guidingText.split('')
        let content = {
          msg: '',
          type: 'doctor',
          contentType: 'text',
          processId: '',
          groupProcessId: '',
          isWelcome: true,
        }
        this.dialogues.push(content)
        let _this = this
        let t = setInterval(() => {
          _this.dialogues[0].msg += texts.shift()
          if (texts.length == 0) {
            clearInterval(t)
            _this.typing = false
            _this.recomQues = item.recomQues ? JSON.parse(item.recomQues) : []
            this.newDialog()
          }
        }, 10)
      },
      addEmptyPop() {
        let content = {
          type: 'doctor',
          msg: '',
          contentType: 'text',
          processId: '',
          groupProcessId: '',
          likeType: 0,
        }
        this.dialogues.push(content)
      },
      checkWsAvailable() {
        console.log('this.ws :>> ', this.ws)
        if (!this.ws || this.ws.readyState == 3) {
          this.initWebSocket()
        }
      },

      /** requests */
      requireBreak() {
        let params = {
          method: 'POST',
          url: '/applet/bigmodel/break',
          data: { userId: this.userId },
        }
        this.req(params).then((res) => {
          this.$message('已停止生成')
        })
      },
      requireReport() {
        let params = {}
      },
      requireHistory(dialogId) {
        let params = {
          method: 'POST',
          url: '/applet/dialog/process/his?pageSize=1000&pageNum=1',
          data: {
            tbDialogueMainId: dialogId,
          },
        }
        this.req(params).then((res) => {
          console.log('history :>> ', res)
          this.formatMsgToData(res.data.data.rows, true)
          this.inDailog = true
        })
      },
      requireNewDialogue() {
        let data = {
          answeUserId: this.answeUserId,
          appMenuId: this.innerAppMenuId,
          userId: this.userId,
        }
        this.req({
          method: 'POST',
          url: '/applet/dialog/creatNewDig',
          data,
        }).then((res) => {
          this.dialogueId = res.data.data.id
          this.inDailog = true
          // this.initWebSocket()
          // this.$emit('newDialogCreated', this.newDialogId)
        })
      },
      requireChat(text) {
        this.autoScroll = true
        this.handelScroll()
        this.recomQues = []
        this.checkWsAvailable()
        this.addEmptyPop()
        this.loading = this.dialogues.length - 1
        let params = {
          method: 'POST',
          url: '/applet/bigmodel/chat',
          data: {
            accessType: 1,
            userId: this.userId,
            answeUserId: this.answeUserId,
            appMenuId: this.innerAppMenuId,
            dialogueId: this.dialogueId,
            prompt: text
              ? text.replace(/\n$/, '')
              : this.inputText.replace(/\n$/, ''),
          },
        }

        this.req(params)
          .then((res) => {
            this.loading = false
            this.inDailog = true
          })
          .catch((err) => {
            console.log('requireChat err :>> ', err)
          })
      },
      async requireChatWithImage() {
        this.recomQues = []
        this.checkWsAvailable()
        if (!this.inDailog) {
          let data = {
            answeUserId: this.answeUserId,
            appMenuId: this.innerAppMenuId,
            userId: this.userId,
          }
          let creatRes = await this.req({
            method: 'POST',
            url: '/applet/dialog/creatNewDig',
            data,
          })
          this.dialogueId = creatRes.data.data.id
        }
        this.addEmptyPop()
        this.loading = this.dialogues.length - 1
        let params = {
          method: 'POST',
          url: '/applet/bigmodel/chat',
          data: {
            accessType: 1,
            userId: this.userId,
            answeUserId: this.answeUserId,
            appMenuId: this.innerAppMenuId,
            dialogueId: this.dialogueId,
            prompt: '',
            image_0: this.imageNameList[0],
            image_1: this.imageNameList[1],
          },
        }
        this.req(params)
          .then((res) => {
            this.inDailog = true
            this.reportId = res.data.data.reportProcessId
          })
          .catch((err) => {
            console.log('requireChatWithImage err :>> ', err)
          })
      },
      async requireNewAndSend(text) {
        this.autoScroll = true
        this.handelScroll()
        this.checkWsAvailable()
        this.handleBreadcrumb(this.innerAppMenuId)
        if (text == '' && this.inputText == '') {
          this.$message('请输入问题')
          return
        }
        let data = {
          answeUserId: this.answeUserId,
          appMenuId: this.innerAppMenuId,
          userId: this.userId,
        }
        let creatRes = await this.req({
          method: 'POST',
          url: '/applet/dialog/creatNewDig',
          data,
        })
        this.dialogueId = creatRes.data.data.id
        // this.initWebSocket()
        this.requireChat(text == '' ? this.inputText : text)
        this.inputText = ''
      },
      requireFeedback(params) {
        this.req({
          method: 'POST',
          url: '/applet/dialog/group/like',
          data: { groupProcessId: params.groupProcessId },
        }).then((res) => {
          this.$message({
            message: '感谢您的反馈',
            type: 'success',
          })
        })
      },
      requireReanswer(processId, index) {
        this.checkWsAvailable()
        let params = {
          method: 'POST',
          url: '/applet/bigmodel/reanswer',
          data: { processId },
        }
        this.loading = index
        this.req(params).then((res) => {
          this.loading = false
        })
      },
      requireProbList() {
        let params = {
          method: 'POST',
          url: '/applet/dialog/feedback/list',
        }
        request(params)
          .then((res) => {
            this.probList = res.data.data
          })
          .catch((res) => {
            console.log('err in feedback :>> ', res)
          })
      },
      req(params) {
        return new Promise((resolve, reject) => {
          request(params)
            .then((res) => {
              if (res.data.code == 401) {
                this.$emit('goLogin')
              } else if (res.data.code != 200) {
                this.$message(res.data.code)
              } else {
                resolve(res)
              }
            })
            .catch((err) => {
              console.log('error in chat container :>> ', err)
              if (err == 401) {
                this.$emit('goLogin')
              }
              if (err == 'ECONNABORTED') {
                this.dialogues[this.loading].msg = '服务器繁忙，请稍后重试'
                this.recomQues = []
                this.loading = false
                this.typing = false
              }
            })
        })
      },
    },
  }
</script>
<style scoped lang="less">
  * {
    box-sizing: border-box;
  }
  .chat-container-wrapper {
    width: 100%;
    height: 100%;
    position: relative;
    display: flex;
    // flex: 1;
    flex-direction: column;
    align-items: center;
  }
  .chat-dialogue-container {
    width: 100%;
    height: calc(100% - 130px);
    padding: 24px 150px 0px 150px;
    overflow-y: auto;
  }
  .chatpop-single-wrapper {
    display: flex;
    flex-direction: column;
    .recommend-question-wrapper {
      display: flex;
      flex-direction: column;
      margin: 12px;
      .recommend-question-text {
        color: #999;
        font-size: 12px;
        line-height: 1.5;
        margin-bottom: 8px;
      }
    }
    .recommend-question {
      display: flex;

      flex-wrap: wrap;

      .recommend-single {
        // height: 32px;
        background: #ffffff;
        border-radius: 10px 10px 10px 10px;
        border: 1px solid rgba(199, 199, 199, 0.6);
        margin-right: 8px;
        margin-bottom: 8px;
        padding: 6px 10px;
        cursor: pointer;
        transition: all 0.2s;
      }
      .recommend-single:hover {
        border: 1px solid #65b0b4;
        background: rgba(101, 176, 180, 0.15);
      }
      .upload-tongue {
        border: 1px solid #65b0b4;
        display: flex;
        align-items: center;
        .up-icon {
          height: 24px;
          width: 24px;
          opacity: 0.8;
        }
        .up-text {
          margin-left: 5px;
          color: #65b0b4;
        }
      }
    }

    .recommend-show-report {
      border: 1px solid #65b0b4;
      color: #65b0b4;
      font-size: 14px;
      margin-top: -40px;
      .report-icon {
        height: 20px;
        margin-bottom: -5px;
      }
    }
  }

  .chat-footer {
    box-sizing: border-box;
    position: absolute;
    width: 100%;
    bottom: 0px;
    // height: 130px;
    padding: 30px 150px 0px 150px;
    display: flex;
    flex-direction: column;
    align-items: center;
    .footer-input-container {
      width: 100%;
      // height: 60px;
      margin-bottom: 8px;
      background: #ffffff;
      border-radius: 16px 16px 16px 16px;
      border: 2px solid #65b0b4;
      box-shadow: 0px 2px 10px 0px rgba(0, 0, 0, 0.08);
      transition: all 0.2s;
      display: flex;
      align-items: end;
      justify-content: space-between;
      padding: 0px 16px;
      .user-input {
        flex-grow: 1;
        // height: 38px;
        border: 0px;
        font-size: 16px;
        margin: 10px 0px;
      }
      .user-input:focus-visible {
        border: 0px;
      }
      .user-upload-icon {
        width: 26px;
        height: 26px;
        margin: 0px 16px;
        cursor: pointer;
      }
      .user-text-send {
        width: 88px;
        height: 38px;
        background: #65b0b4;
        border-radius: 8px 8px 8px 8px;
        // margin: 10px 0px;
      }
    }
    .footer-notice {
      font-size: 14px;
      color: #999999;
      line-height: 16px;
      .agreement {
        line-height: 16px;
        color: #65b0b4;
      }
    }
  }
  .report-container {
    z-index: 2999;
  }
  .chat-loading {
    margin: 20px 12px 12px 12px;
  }
  .loading-img {
    height: 10px;
    // width: 120px;
  }
  .user-operation {
    display: flex;
    align-items: center;
    // margin-bottom: 10px;
    align-self: end;
    margin-bottom: 10px;
  }
  .fade-in {
    animation: easein 0.5s;
  }
  @keyframes easein {
    from {
      opacity: 0;
      transform: translateY(20px);
    }
    to {
      opacity: 1;
      transform: translateY(0px);
    }
  }
  /deep/ .el-textarea__inner:focus {
    border-color: rgba(255, 255, 255, 0);
  }
  /deep/ .el-textarea__inner:hover {
    border-color: rgba(255, 255, 255, 0);
  }
  /deep/ .el-textarea__inner {
    border-color: rgba(255, 255, 255, 0);
  }
  /deep/ .el-textarea .el-input__count {
    right: 20px;
    margin-bottom: -12px;
  }
</style>
